#include "stdafx.h"
#include "Vector4.h"


CVector4::CVector4(void)
	: x(0.0)
	, y(0.0)
	, z(0.0)
	, w(0.0)
{
}


CVector4::CVector4(double a,double b,double c,double d)
	: x(a)
	, y(b)
	, z(c)
	, w(d)
{

}

CVector4::CVector4(const CVector4& v)
	: x(v.x)
	, y(v.y)
	, z(v.z)
	, w(v.w)
{

}

CVector4::~CVector4(void)
{
}

CVector4& CVector4::operator=(const CVector4& v)
{
	if (this==&v) return *this;

	x = v.x;
	y = v.y;
	z = v.z;
	w = v.w;

	return *this;
}

DString CVector4::PrintSelf()
{
	DString str;
	str.Format(_T("(%.1f,%.1f,%.1f,%.1f)"),x,y,z,w);
	return str;
}

double CVector4::Dot(const CVector4 pt) const 
{
	return CVector4::Dot(*this,pt);
}

double CVector4::Dot(const CVector4 pt1,const CVector4 pt2)
{
	return (pt1.x*pt2.x + pt1.y*pt2.y + pt1.z*pt2.z);
}

void CVector4::Sub(const CVector4& pt)
{
	*this = CVector4::Sub(*this,pt);
}

CVector4 CVector4::Sub(CVector4& pt1,const CVector4& pt2)
{
	CVector4 out;
	out.x = pt1.x - pt2.x;
	out.y = pt1.y - pt2.y;
	out.z = pt1.z - pt2.z;
	//out.w = pt1.w - pt2.w;
	return out;
}

CVector4 CVector4::operator-(CVector4 pt) const
{
	CVector4 out;
	out = *this;
	out.Sub(pt);
	return out;
}

void CVector4::Add(const CVector4& pt) 
{
	*this = CVector4::Add(*this,pt);

}

CVector4 CVector4::Add(const CVector4& pt1,const CVector4& pt2)
{
	CVector4 out;
	out.x = pt1.x + pt2.x;
	out.y = pt1.y + pt2.y;
	out.z = pt1.z + pt2.z;
	out.w = pt1.w;
	return out;
}

CVector4 CVector4::operator+(CVector4 pt) const
{
	CVector4 out;
	out = *this;
	out.Add(pt);
	return out;
}

void CVector4::MulScalar(const double k)
{
	*this = CVector4::MulScalar(*this,k);
}

CVector4 CVector4::MulScalar(const CVector4& pt,const double k)
{
	CVector4 out;
	out.x = pt.x * k;
	out.y = pt.y * k;
	out.z = pt.z * k;
	out.w = pt.w;
	return out;
}

CVector4 CVector4::operator*(float t) const
{
	CVector4 pt;
	pt = *this;
	pt.MulScalar(t);

	return pt;
}

double CVector4::AngleBetweenVectors(const CVector4& v1, const CVector4& v2)
{
	//double cross[3];
	//vtkMath::Cross(v1, v2, cross);
	//return atan2(vtkMath::Norm(cross), vtkMath::Dot(v1, v2));
	CVector4 cross;
	cross = CVector4::Cross(v1,v2);
	double n = CVector4::Norm(cross);
	double d = CVector4::Dot(v1, v2);

	return atan2(n, d);

}

double CVector4::Distance2BetweenPoints(const CVector4& p1, const CVector4& p2)
{
	return ( ( p1.x - p2.x ) * ( p1.x - p2.x )
		+ ( p1.y - p2.y ) * ( p1.y - p2.y )
		+ ( p1.z - p2.z ) * ( p1.z - p2.z ) );
}



CVector4 CVector4::Cross(const CVector4& v1, const CVector4& v2)
{
	CVector4 out;

	//double Cx = a[1] * b[2] - a[2] * b[1];
	//double Cy = a[2] * b[0] - a[0] * b[2];
	//double Cz = a[0] * b[1] - a[1] * b[0];
	//c[0] = Cx; c[1] = Cy; c[2] = Cz;

	out.x = v1.y * v2.z - v1.z * v2.y;
	out.y = v1.z * v2.x - v1.x * v2.z;
	out.z = v1.x * v2.y - v1.y * v2.x;
	out.w = 0.0;

	return out;
}


CVector4 CVector4::Cross(const CVector4& v) const
{
	return CVector4::Cross(*this, v);
}

double CVector4::Norm(const CVector4& v)
{
	return sqrt(v.x*v.x + v.y*v.y + v.z*v.z);
}

double CVector4::Norm() const
{
	return CVector4::Norm(*this);
}

double CVector4::SqrNorm()
{
	return x*x + y*y + z*z;
}


void CVector4::Normalize()
{
	double norm = Norm();
	MulScalar(1.0/norm);
}

void CVector4::SetValue(double a,double b,double c,double d)
{
	x = a;
	y = b;
	z = c;
	w = d;
}
